
package tp.pr5.mv.instructions;

import tp.pr5.mv.Instruction;
import tp.pr5.mv.Memory;
import tp.pr5.mv.OperandStack;
import tp.pr5.mv.ProgramCounter;
import tp.pr5.mv.inout.InMethod;
import tp.pr5.mv.inout.OutMethod;
import tp.pr5.mv.traps.MVTrap;
import tp.pr5.mv.traps.WithoutOperandsEx;


public abstract class BinaryInstructions extends Instruction {
	
	public void execute ( OperandStack stack, Memory mem, ProgramCounter pc, InMethod inMethod, OutMethod outMethod ) throws MVTrap {
			
		    if (stack.getCounter() < 2)    // Necesitamos al menos dos operandos en la pila.
		    	throw new WithoutOperandsEx( this, stack.getCounter() );    // Lanzamos la excepción pues no hay suf. operandos en la pila.
		
			
			// Guardamos los valores en dos variables locales, retiramos los operandos de la pila 
    	    // y cargamos en la pila un resultado que depende del tipo de instrucción (implementado en las clases hijas).		
    	
			int a = stack.top(); 
			int b = stack.subtop();
			
			int resultado = combine( a, b );    // El método combine lanza la excepción de División por 0 si se diese.
			
			stack.pop();
			stack.pop();
			
			stack.push( resultado ); 
									

					
	}
	
	public abstract int combine( int op1, int op2 ) throws MVTrap;
	 
}
